<template>
  <div class="channels">
    <!-- 上面的部分：我的频道 -->
    <div class="panel">
      <div class="title">
        <span>我的频道</span>
        <van-button @click="delShow = !delShow" type="danger" plain size="mini"
          >
          {{ delShow ? '取消' : '编辑' }}
          </van-button
        >
      </div>

      <van-grid>
        <van-grid-item
          class="my-item"
          v-for="(item, index) in ownChannels"
          :key="item.id"
          :class="{ active: index == idx }"
          @click="changeActive(index)"
        >
          {{ item.name }}

          <!-- x -->
          <van-icon @click="doDel(index)" v-show="delShow && index != 0" name="cross" />
        </van-grid-item>
      </van-grid>
    </div>

    <!-- 下面的部分：可选频道 -->
    <div class="panel">
      <div class="title">
        <span>可选频道</span>
      </div>

      <van-grid>
        <van-grid-item
          v-for="item in optList"
          :key="item.id"
          @click="addChannel(item)"
        >
          {{ item.name }}
        </van-grid-item>
      </van-grid>
    </div>
  </div>
</template>

<script>
// 导入接口
import { setChannelsAPI } from "@/api";
import { saveChannels } from "@/utils/storage";

export default {
  props: {
    // 要父组件传递一个ownChannels过来
    ownChannels: {
      // 必须要传，不传就会报错
      required: true,
      // 还要限制传递的数据是数组
      type: Array,
    },

    allChannels: {
      required: true,
      type: Array,
    },

    // 子接受的参数名叫 value
    idx: {
      // 必须传一个number类型的数据进来
      required: true,
      type: Number,
    },
  },

  data() {
    return {
      delShow: false,
    };
  },

  // 在组件内部写一个属性叫model属性
  // 就是在告诉外界调用我这个组件时，如果用v-model该怎么生成代码
  // 用prop告诉外界应该生成什么样的父传子，用event告诉外界应该生成什么样的子传父
  // 它是在告诉编译器，到时候你帮我生成事件的时候，原本你是该生成@input的，但是不要了
  // 你给我生成 @changeActive,同样也告诉了编译器，你帮我生成父传子属性时候，原本该生成的
  // 是 :value="数据" ，但不要了，帮我改成 :idx="数据"
  model: {
    prop: "idx",
    event: "changeActive",
  },

  methods: {
    async addChannel(item) {
      // 谁被点，就把谁加到我的频道里
      this.ownChannels.push(item);

      // 加到数组后要做数据的持久化
      // 先判断有没有登录
      if (this.$store.state.tokenObj.token) {
        // 代表登录了，就发请求
        // 此时我们是想保存最新的 `我的频道`，换句话说就是保存ownChannels数组
        // 但是这个数组不能直接传递给服务器，因为服务器要的格式不一样
        // 所以就应该按照ownChannels做一个提取新数组
        let channels = this.ownChannels.map((v, index) => {
          return { id: v.id, seq: index + 1 };
        });

        await setChannelsAPI({ channels });
      } else {
        // 代表没登录，就保存到本地存储
        saveChannels(this.ownChannels);
      }
    },

    // 点击我的频道的事件
    changeActive(index) {
      // 1. 把这个下标传递给父组件
      // 子传父时我又把事件名特意写成了input
      this.$emit("changeActive", index);
      // 2. 关闭频道面板
      // 通知父组件关闭频道(因为她要操作父组件里的数据，而子组件没法操作，所以通知)
      this.$emit("close");
    },


    // 删除的点击事件
    async doDel (index) {

      // 根据下标删除即可
      this.ownChannels.splice(index, 1)

      // 先判断有没有登录
      if (this.$store.state.tokenObj.token) {
        
        let channels = this.ownChannels.map((v, index) => {
          return { id: v.id, seq: index + 1 };
        });

        await setChannelsAPI({ channels });

      } else {
        // 代表没登录，就保存到本地存储
        saveChannels(this.ownChannels);
      }
    }
  },

  computed: {
    // 计算属性：获取可选频道
    optList() {
      // 从所有频道里排除掉我的频道，剩余的就是可选频道
      // 换句话说，就过滤出来所有不在我的频道里的数据
      return this.allChannels.filter(
        (v) =>
          // 判断这个元素不在我的频道里，就过滤出来，否则不过滤出来
          this.ownChannels.findIndex((val) => val.id == v.id) == -1
      );
    },
  },
};
</script>

<style lang="less" scoped>
.channels {
  padding: 0 20px;

  .panel {
    margin-top: 20px;

    .title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 10px;
    }

    .active {
      color: #f00;
    }
  }

  .my-item {
    position: relative;

    .van-icon {
      position: absolute;
      right: 5px;
      top: 5px;
    }
  }
}
</style>